﻿//***********************************************************************************************
//* File Name	: App.xaml.cs
//* Description	: This is class to implement MainWindow User Interface
//* 
//* Author		: Ashutosh Phoujdar(ashu.fouzdar@gmail.com)
//* Date		: 14-September-2014
//*

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Win32;
using EmailFactory;
using ActiveUp.Net.Mail;
using System.Text.RegularExpressions;
using System.Diagnostics;
using System.Data;
using System.IO;

namespace EmailCommander
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private const string userRoot = "HKEY_CURRENT_USER\\SOFTWARE\\";
        private string LoggingFile = "JobHistory.xml";
        private System.Windows.Threading.DispatcherTimer timer;
        private DataTable dtJobHistory = new DataTable();

        public MainWindow()
        {
            LoggingFile = Directory.GetCurrentDirectory() + "\\JobHistory.xml";
            dtJobHistory = GetLoggingInfo();
            InitializeComponent();

            this.Closing += MainWindow_Closing;
            this.myNotifyIcon.TrayMouseDoubleClick += myNotifyIcon_TrayMouseDoubleClick;
            grdJobHistory.DataContext = dtJobHistory.DefaultView;
            LoadConfig();

        }

        void myNotifyIcon_TrayMouseDoubleClick(object sender, RoutedEventArgs e)
        {
            this.Show();
        }

        void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            SaveConfig();
            if(MessageBox.Show("Do you want to minimize to System Tray","Confirm",MessageBoxButton.YesNo)== MessageBoxResult.Yes)
            {
                e.Cancel = true;
                this.Hide();
            }
        }

        private void LoadConfig()
        {
            string emailServer = Convert.ToString(Registry.GetValue(userRoot + "EmailCommander", "EmailServer", string.Empty));
            txtEmailServer.Text = emailServer;

            string emailServerPort = Convert.ToString(Registry.GetValue(userRoot + "EmailCommander", "EmailServerPort", string.Empty));
            txtEmailServerPort.Text = emailServerPort;

            bool isSsl = Convert.ToBoolean(Registry.GetValue(userRoot + "EmailCommander", "IsSSL", true));
            chkSSL.IsChecked = isSsl;

            bool isImap = Convert.ToBoolean(Registry.GetValue(userRoot + "EmailCommander", "IsIMAP", true));
            optImap.IsChecked = isImap;

            bool isPop = Convert.ToBoolean(Registry.GetValue(userRoot + "EmailCommander", "IsPOP", true));
            optPop.IsChecked = isPop;

            string userName = Convert.ToString(Registry.GetValue(userRoot + "EmailCommander", "UserName", string.Empty));
            txtUserName.Text = userName;

            string password = Convert.ToString(Registry.GetValue(userRoot + "EmailCommander", "Password", string.Empty));
            txtPassword.Password = password;

            string subjectPrefix = Convert.ToString(Registry.GetValue(userRoot + "EmailCommander", "SubjectPrefix", string.Empty));
            txtSubjectPrefix.Text = subjectPrefix;

            string cmdSeparator = Convert.ToString(Registry.GetValue(userRoot + "EmailCommander", "CommandSeperator", string.Empty));
            txtCommandSeparator.Text = cmdSeparator;

            string pollingTime = Convert.ToString(Registry.GetValue(userRoot + "EmailCommander", "PollingTime", "5"));
            txtPollingTime.Text = pollingTime;
        }

        private void SaveConfig()
        {
            Registry.SetValue(userRoot + "EmailCommander", "EmailServer", txtEmailServer.Text);
            Registry.SetValue(userRoot + "EmailCommander", "EmailServerPort", txtEmailServerPort.Text);
            Registry.SetValue(userRoot + "EmailCommander", "IsSSL", chkSSL.IsChecked);
            Registry.SetValue(userRoot + "EmailCommander", "IsIMAP", optImap.IsChecked);
            Registry.SetValue(userRoot + "EmailCommander", "IsPOP", optPop.IsChecked);
            Registry.SetValue(userRoot + "EmailCommander", "UserName", txtUserName.Text);
            Registry.SetValue(userRoot + "EmailCommander", "Password", txtPassword.Password);
            Registry.SetValue(userRoot + "EmailCommander", "SubjectPrefix", txtSubjectPrefix.Text);
            Registry.SetValue(userRoot + "EmailCommander", "CommandSeperator", txtCommandSeparator.Text);
            Registry.SetValue(userRoot + "EmailCommander", "PollingTime", txtPollingTime.Text);
       }

        private void btnStartStop_Click(object sender, RoutedEventArgs e)
        {
            if(btnStartStop.Content.Equals("Start"))
            {
                if (this.timer == null)
                {
                    timer = new System.Windows.Threading.DispatcherTimer();
                    timer.Tick += timer_Tick;
                }
                timer.Interval = new TimeSpan(0,Convert.ToInt32(txtPollingTime.Text), 0);
                timer.Start();
                btnStartStop.Content = "Stop";
                ChangeControlState(false);
            }
            else
            {
                if (this.timer != null && timer.IsEnabled)
                    timer.Stop();
                btnStartStop.Content = "Start";
                ChangeControlState(true);
            }
        }

        void timer_Tick(object sender, EventArgs e)
        {
            lock (dtJobHistory)
            {
                if ((bool)optImap.IsChecked)
                {
                    IEmailRepository repository = EmailClientFactory.GetFactory().GetImapRepository(txtEmailServer.Text,
                        Convert.ToInt32(txtEmailServerPort.Text),
                        (bool)chkSSL.IsChecked,
                        txtUserName.Text,
                        txtPassword.Password);

                    if (repository != null)
                    {
                        MessageCollection messages = repository.GetUnreadMails("Inbox");
                        foreach (Message msg in messages)
                        {
                            if (msg.Subject.StartsWith(txtSubjectPrefix.Text, StringComparison.InvariantCultureIgnoreCase))
                            {
                                try
                                {
                                    string command = Regex.Replace(msg.Subject, txtSubjectPrefix.Text, string.Empty, RegexOptions.IgnoreCase | RegexOptions.Multiline);
                                    string[] commandParts = command.Split(txtCommandSeparator.Text.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                                    Process process = new Process();
                                    ProcessStartInfo startInfo = new ProcessStartInfo(System.IO.Directory.GetCurrentDirectory() + "\\PsExec.exe");
                                    startInfo.Arguments = string.Format("\\\\{0} {1}", commandParts[0], commandParts[1]);
                                    //ProcessStartInfo startInfo = new ProcessStartInfo("cmd.exe");
                                    //startInfo.Arguments = " /c ipconfig /all";
                                    startInfo.UseShellExecute = false;
                                    startInfo.RedirectStandardInput = true;
                                    startInfo.RedirectStandardOutput = true;
                                    startInfo.RedirectStandardError = true;

                                    process.StartInfo = startInfo;
                                    process.Start();
                                    // Read the output stream first and then wait.
                                    string output = process.StandardOutput.ReadToEnd();
                                    output += process.StandardError.ReadToEnd();
                                    process.WaitForExit();

                                    DataRow newRow = dtJobHistory.NewRow();
                                    newRow["MachineName"] = commandParts[0];
                                    newRow["Command"] = commandParts[1];
                                    newRow["Output"] = output;
                                    newRow["RequestedBy"] = msg.From.Email;
                                    dtJobHistory.Rows.Add(newRow);
                                }
                                catch (Exception exp)
                                {
                                    MessageBox.Show(exp.Message, exp.Source);
                                }

                            }
                        }
                        dtJobHistory.WriteXml(LoggingFile, XmlWriteMode.WriteSchema);
                        grdJobHistory.DataContext = dtJobHistory.DefaultView;
                    }
                }
                else
                {
                    throw new NotImplementedException();
                }
            }
        }

        private DataTable GetLoggingInfo()
        {
            DataTable dt = new DataTable("LoggingInfo");
            if (System.IO.File.Exists(LoggingFile))
            {
                dt.ReadXml(LoggingFile);
            }
            else
            {
                dt.Columns.Add("MachineName", typeof(string));
                dt.Columns.Add("Command", typeof(string));
                dt.Columns.Add("Output", typeof(string));
                dt.Columns.Add("RequestedBy", typeof(string));
            }
            return dt;
        }

        private void ChangeControlState(bool state)
        {
            foreach (TextBox textBox in FindVisualChildren<TextBox>(MainWindow1))
            {
                textBox.IsEnabled = state;
            }

            foreach (PasswordBox textBox in FindVisualChildren<PasswordBox>(MainWindow1))
            {
                textBox.IsEnabled = state;
            }

            foreach (CheckBox chkBox in FindVisualChildren<CheckBox>(MainWindow1))
            {
                chkBox.IsEnabled = state;
            }

            foreach (RadioButton radioBtn in FindVisualChildren<RadioButton>(MainWindow1))
            {
                radioBtn.IsEnabled = state;
            }
        }

        public IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
        {
            if (depObj != null)
            {
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
                {
                    DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                    if (child != null && child is T)
                    {
                        yield return (T)child;
                    }

                    foreach (T childOfChild in FindVisualChildren<T>(child))
                    {
                        yield return childOfChild;
                    }
                }
            }
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            IEmailRepository repository = EmailClientFactory.GetFactory().GetImapRepository(txtEmailServer.Text, 
                    Convert.ToInt32(txtEmailServerPort.Text), 
                    (bool)chkSSL.IsChecked, 
                    txtUserName.Text, 
                    txtPassword.Password);

            if (repository != null)
            {
                Message message = repository.GetMailByOrdinal("Inbox",10);
            }
        }
    }
}
